package dm.com.dmexamples.image_chooser;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dm.com.dmexamples.App;
import dm.com.dmexamples.R;

/**
 * 用bean绑定的adapter
 */
public abstract class BeanAdapter<T> extends BaseAdapter {

    public List<T> mVaules = null;

    public void setmVaules(List<T> mVaules) {
        this.mVaules = mVaules;
    }

    private final Object mLock = new Object();

    protected int mResource;

    protected int mDropDownResource;

    protected boolean mNotifyOnChange = true;

    private LayoutInflater mInflater;

    public Map<Integer, InViewClickListener> canClickItem;

    public boolean isReuse = true;

    public Context mContext;


    public Class<?> jumpClazz;
    public String jumpKey;
    public String jumpAs;

    public Class<?> getJumpClazz() {
        return jumpClazz;
    }

    public String getJumpKey() {
        return jumpKey;
    }

    public String getJumpAs() {
        return jumpAs;
    }

    public void setJump(Class<?> jumpClazz, String jumpkey, String as) {
        this.jumpClazz = jumpClazz;
        this.jumpKey = jumpkey;
        this.jumpAs = as;
    }

    public BeanAdapter(Context context, int mResource, boolean isViewReuse) {
        super();
        this.mResource = mResource;
        isReuse = isViewReuse;
        this.mDropDownResource = mResource;
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mVaules = new ArrayList<T>();
    }

    public BeanAdapter(Context context, int mResource) {
        this(context, mResource, true);
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> getValues() {
        return (List<T>) mVaules;
    }

    public void add(T one) {
        synchronized (mLock) {
            mVaules.add(one);
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void add(int to, T entry) {
        synchronized (mLock) {
            mVaules.add(to, entry);
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void addAll(List<T> ones) {
        synchronized (mLock) {
            mVaules.addAll(ones);
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void insert(int index, T one) {
        synchronized (mLock) {
            if (index < 0)
                index = 0;
            mVaules.add(index, one);
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void remove(int index) {
        synchronized (mLock) {
            if (index < mVaules.size() && index >= 0) {
                mVaules.remove(index);
            }
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void clear() {
        synchronized (mLock) {
            mVaules.clear();
        }
        if (mNotifyOnChange)
            notifyDataSetChanged();
    }

    public void setNotifyOnChange(boolean notifyOnChange) {
        mNotifyOnChange = notifyOnChange;
    }

    @Override
    public int getCount() {
        return mVaules.size();
    }

    @Override
    public Object getItem(int position) {
        if (position < mVaules.size() && position >= 0) {
            return mVaules.get(position);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public <T> T getTItem(int position) {
        if (position < mVaules.size() && position >= 0) {
            return (T) mVaules.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public String getTItemId(int position) {

        return position + "";
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        if (isReuse) {
            if (convertView == null) {
                view = mInflater.inflate(mResource, parent, false);
            } else {
                view = convertView;
            }

        } else {
            if (convertView != null) {
                parent.removeView(convertView);
            }
            view = mInflater.inflate(mResource, parent, false);
        }
        bindView(view, position, mVaules.get(position));
        bindInViewListener(view, position, mVaules.get(position));
        return view;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {
            view = mInflater.inflate(mDropDownResource, parent, false);
        } else {
            view = convertView;
        }
        bindView(view, position, mVaules.get(position));
        bindInViewListener(view, position, mVaules.get(position));
        return view;
    }

    public abstract void bindView(View itemV, int position, T jo);

    /**
     * 将值和控件绑定 可以防止图片的移位
     *
     * @param position
     * @param v
     * @param o
     */
    public void bindValue(final Integer position, View v, Object o) {
        if (o == null)
            o = "";
        if (v instanceof ImageView) {
            ImageView imagev = (ImageView) v;
            if (o instanceof Drawable) {
                imagev.setImageDrawable((Drawable) o);
            } else if (o instanceof Bitmap) {
                imagev.setImageBitmap((Bitmap) o);
            } else if (o instanceof Integer) {
                imagev.setImageResource((Integer) o);
            } else if (o instanceof String) {
                Glide.with(App.getInstance()).load((String) o).centerCrop().crossFade().placeholder(R.mipmap.ic_launcher).into((ImageView) v);
            }
        } else if (v instanceof TextView) {
            if (o instanceof CharSequence) {
                ((TextView) v).setText((CharSequence) o);
            } else {
                ((TextView) v).setText(o.toString());
            }
        }
    }

    private void bindInViewListener(final View itemV, final Integer position, final Object valuesMap) {
        if (canClickItem != null) {
            for (Integer key : canClickItem.keySet()) {
                View inView = itemV.findViewById(key);
                final InViewClickListener inviewListener = canClickItem.get(key);
                if (inView != null && inviewListener != null) {
                    inView.setOnClickListener(new OnClickListener() {

                        public void onClick(View v) {
                            inviewListener.OnClickListener(itemV, v, position, valuesMap);
                        }
                    });
                }
            }
        }
    }

    public void setOnInViewClickListener(Integer key, InViewClickListener inViewClickListener) {
        if (canClickItem == null)
            canClickItem = new HashMap<Integer, InViewClickListener>();
        canClickItem.put(key, inViewClickListener);
    }

    public void setmDropDownResource(int mDropDownResource) {
        this.mDropDownResource = mDropDownResource;
    }

    public int getmDropDownResource() {
        return mDropDownResource;
    }

    public interface InViewClickListener {
        public void OnClickListener(View parentV, View v, Integer position, Object values);
    }


    public void notifyDataSetChanged(List<T> t) {
        super.notifyDataSetChanged();
        mVaules = t;
    }

    /**
     * 刷新单独一个item
     */
    public void refreshItemView(int position, T bean, ListView mListView) {
        // 得到第一个可显示控件的位置，
        int visiblePosition = mListView.getFirstVisiblePosition();
        // 只有当要更新的view在可见的位置时才更新，不可见时，跳过不更新
        if (position - visiblePosition >= 0) {
            // 得到要更新的item的view
            View view = mListView.getChildAt(position - visiblePosition);
            // 从view中取得holder
            mVaules.set(position, bean);
            getView(position, view, mListView);
        }

    }

    /**
     * 删除某一条item
     */
    public void removeItemView(int position, ListView mListView) {
        // 得到第一个可显示控件的位置，
        int visiblePosition = mListView.getFirstVisiblePosition();
        // 只有当要更新的view在可见的位置时才更新，不可见时，跳过不更新
        if (position - visiblePosition >= 0) {
            // 得到要更新的item的view
            View view = mListView.getChildAt(position - visiblePosition);
            // 从view中取得holder
            mVaules.remove(position);
            getView(position, view, mListView);
        }

    }

    /**
     * viewholder
     */
    public static class ViewHolder {
        Map<Integer, View> views;
        View itemV;

        public static ViewHolder getHolder(View itemV) {
            ViewHolder viewHolder = (ViewHolder) itemV.getTag();
            if (viewHolder == null) {
                viewHolder = new ViewHolder();
                itemV.setTag(viewHolder);
                viewHolder.itemV = itemV;
            }
            return viewHolder;
        }

        public View getView(Integer id) {
            View v = views.get(id);
            if (v == null) {
                v = itemV.findViewById(id);
                if (v != null) {
                    views.put(id, v);
                }
            }
            return v;
        }

        private ViewHolder() {
            super();
            views = new HashMap<Integer, View>();
        }

    }

}
